<template>
  <div ref="chart" style="width: 100%; height: 100%" />
</template>

<script>
import * as echarts from 'echarts'

export default {
  name: 'PieChart',
  props: {
    value: {
      type: Number,
      default: 0,
      validator: (value) => value >= 0 && value <= 100
    }
  },
  data() {
    return {
      chart: null,
      timerId: null
    }
  },
  watch: {
    value: {
      deep: true,
      handler() {
        this.initChart()
      }
    }
  },
  mounted() {
    this.initChart()
    window.addEventListener('resize', this.handleResize)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.handleResize)
    if (this.chart) {
      this.chart.dispose()
    }
    if (this.timerId) {
      clearInterval(this.timerId)
    }
  },
  methods: {
    initChart() {
      if (!this.chart) {
        this.chart = echarts.init(this.$refs.chart)
      }
      // 做环形图的本质是 radius: ['内半径', '外半径'] 内半径!=0
      // 画渐变色的原理是：data里面可以设置itemStyle
      let angle = 0 // 角度，用来做简单的动画效果的
      let timerId
      const colors = ['#A098FC', '#4386FA', '#4FADFD', '#0CD3DB', '#646CF9']
      const innerRingColor = {
        type: 'linear',
        x: 0,
        y: 0,
        x2: 0,
        y2: 1,
        colorStops: [0, 0.3, 0.6, 0.8, 1].map((offset, index) => ({
          offset,
          color: colors[index]
        })),
        global: false // 缺省为 false
      }
      const option = {
        color: colors,
        title: {
          textStyle: {
            color: '#fff',
            fontSize: 16
          },
          padding: 0,
          top: 35,
          left: 'center'
        },
        tooltip: {
          show: false
        },
        legend: {
          show: false
        },
        series: [
          {
            name: '',
            type: 'pie',
            center: ['50%', '50%'], // 圆心的位置
            radius: ['43%', '47%'], // 原为["32%", "35%"]，内外半径都增大
            avoidLabelOverlap: false, // 做同心圆用到
            clockwise: false, // 顺时针排列
            startAngle: 90, // 起始角度 影响不大
            label: {
              show: true, // false不显示饼图上的标签
              position: 'center', // inside（在饼图上显示）,outside(默认就会出现引导线) center
              formatter: `${this.value}%`, // 修改这里，使用 this.value
              fontSize: 26,
              fontWeight: 'bold',
              color: '#fff' // 添加这一行设置文字颜色为白色
            },
            data: [
              {
                value: this.value, // 修改这里
                name: '完成',
                itemStyle: { color: innerRingColor, opacity: 1 }
              },
              {
                value: 100 - this.value, // 修改这里
                name: '未完成',
                itemStyle: { color: '#282c40' }
              }
            ].sort((a, b) => b.value - a.value), // 数组从大到小排序
            emphasis: {
              scale: false
            }
          },
          {
            name: '',
            type: 'pie',
            center: ['50%', '50%'], // 圆心的位置
            radius: ['58%', '68%'], // 原为["40%", "50%"]，内外半径都增大
            avoidLabelOverlap: false, // 做同心圆用到
            clockwise: false, // 顺时针排列
            startAngle: 90, // 起始角度 影响不大
            label: {
              show: false // false不显示饼图上的标签
            },
            data: [
              {
                value: this.value,
                name: '完成',
                itemStyle: { color: innerRingColor, opacity: 1 }
              },
              {
                value: 100 - this.value,
                name: '未完成',
                itemStyle: { color: '#282c40' }
              }
            ].sort((a, b) => b.value - a.value), // 数组从大到小排序
            emphasis: {
              scale: false
            }
          },
          {
            name: 'ring5',
            type: 'custom',
            coordinateSystem: 'none',
            renderItem: function(params, api) {
              return {
                type: 'arc',
                shape: {
                  cx: api.getWidth() / 2,
                  cy: api.getHeight() / 2,
                  r: (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.8,
                  startAngle: ((0 + angle) * Math.PI) / 180,
                  endAngle: ((90 + angle) * Math.PI) / 180
                },
                style: {
                  stroke: colors[0],
                  fill: 'transparent',
                  lineWidth: 1.5
                },
                silent: true
              }
            },
            data: [0]
          },
          {
            name: 'ring5',
            type: 'custom',
            coordinateSystem: 'none',
            renderItem: function(params, api) {
              const x0 = api.getWidth() / 2
              const y0 = api.getHeight() / 2
              const r = (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.8
              const point = getCirlPoint(x0, y0, r, 90 + angle)
              return {
                type: 'circle',
                shape: {
                  cx: point.x,
                  cy: point.y,
                  r: 4
                },
                style: {
                  stroke: colors[0],
                  fill: colors[0]
                },
                silent: true
              }
            },
            data: [0]
          },
          // 蓝色
          {
            name: 'ring5',
            type: 'custom',
            coordinateSystem: 'none',
            renderItem: function(params, api) {
              return {
                type: 'arc',
                shape: {
                  cx: api.getWidth() / 2,
                  cy: api.getHeight() / 2,
                  r: (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.8,
                  startAngle: ((180 + angle) * Math.PI) / 180,
                  endAngle: ((270 + angle) * Math.PI) / 180
                },
                style: {
                  stroke: colors[1],
                  fill: 'transparent',
                  lineWidth: 1.5
                },
                silent: true
              }
            },
            data: [0]
          },
          {
            name: 'ring5', // 蓝色
            type: 'custom',
            coordinateSystem: 'none',
            renderItem: function(params, api) {
              const x0 = api.getWidth() / 2
              const y0 = api.getHeight() / 2
              const r = (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.8
              const point = getCirlPoint(x0, y0, r, 180 + angle)
              return {
                type: 'circle',
                shape: {
                  cx: point.x,
                  cy: point.y,
                  r: 4
                },
                style: {
                  stroke: colors[1], // 绿
                  fill: colors[1]
                },
                silent: true
              }
            },
            data: [0]
          },
          {
            name: 'ring5',
            type: 'custom',
            coordinateSystem: 'none',
            renderItem: function(params, api) {
              return {
                type: 'arc',
                shape: {
                  cx: api.getWidth() / 2,
                  cy: api.getHeight() / 2,
                  r: (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.95,
                  startAngle: ((270 + -angle) * Math.PI) / 180,
                  endAngle: ((40 + -angle) * Math.PI) / 180
                },
                style: {
                  stroke: colors[2],
                  fill: 'transparent',
                  lineWidth: 1.5
                },
                silent: true
              }
            },
            data: [0]
          },
          // 橘色
          {
            name: 'ring5',
            type: 'custom',
            coordinateSystem: 'none',
            renderItem: function(params, api) {
              return {
                type: 'arc',
                shape: {
                  cx: api.getWidth() / 2,
                  cy: api.getHeight() / 2,
                  r: (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.95,
                  startAngle: ((90 + -angle) * Math.PI) / 180,
                  endAngle: ((220 + -angle) * Math.PI) / 180
                },
                style: {
                  stroke: colors[2],
                  fill: 'transparent',
                  lineWidth: 1.5
                },
                silent: true
              }
            },
            data: [0]
          },
          {
            name: 'ring5',
            type: 'custom',
            coordinateSystem: 'none',
            renderItem: function(params, api) {
              const x0 = api.getWidth() / 2
              const y0 = api.getHeight() / 2
              const r = (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.95
              const point = getCirlPoint(x0, y0, r, 90 + -angle)
              return {
                type: 'circle',
                shape: {
                  cx: point.x,
                  cy: point.y,
                  r: 4
                },
                style: {
                  stroke: colors[3], // 粉
                  fill: colors[3]
                },
                silent: true
              }
            },
            data: [0]
          },
          {
            name: 'ring5', // 绿点
            type: 'custom',
            coordinateSystem: 'none',
            renderItem: function(params, api) {
              const x0 = api.getWidth() / 2
              const y0 = api.getHeight() / 2
              const r = (Math.min(api.getWidth(), api.getHeight()) / 2) * 0.95
              const point = getCirlPoint(x0, y0, r, 270 + -angle)
              return {
                type: 'circle',
                shape: {
                  cx: point.x,
                  cy: point.y,
                  r: 4
                },
                style: {
                  stroke: colors[3], // 绿
                  fill: colors[3]
                },
                silent: true
              }
            },
            data: [0]
          }
        ]
      }

      // 获取圆上面某点的坐标(x0,y0表示坐标，r半径，angle角度)
      function getCirlPoint(x0, y0, r, angle) {
        const x1 = x0 + r * Math.cos((angle * Math.PI) / 180)
        const y1 = y0 + r * Math.sin((angle * Math.PI) / 180)
        return {
          x: x1,
          y: y1
        }
      }

      // 修改 draw 函数为箭头函数以保持 this 上下文
      const draw = () => {
        angle = angle + 3
        this.chart.setOption(option, true)
      }

      draw()

      setTimeout(() => {
        if (timerId) {
          clearInterval(timerId)
        }
        timerId = setInterval(() => {
          draw()
        }, 100)
      }, 500)
    },

    handleResize() {
      this.chart && this.chart.resize()
    }
  }
}
</script>
